package ext

inline fun Byte.toInt8() = this.toInt() and 0xFF

inline fun Byte.toLong8() = this.toLong() and 0xFF

inline fun ByteArray.arg(index: Int) = this[index + 2].toInt8()

fun ByteArray.argInt(index: Int): Int {
    return  ((this[index + 0 + 2].toInt8() and 0x7F) shl 21) +
            ((this[index + 1 + 2].toInt8() and 0x7F) shl 14) +
            ((this[index + 2 + 2].toInt8() and 0x7F) shl 7) +
            ((this[index + 3 + 2].toInt8() and 0x7F))
}

fun ByteArray.argShort(index: Int): Int {
    return  ((this[index + 0 + 2].toInt8() and 0x7F) shl 7) +
            ((this[index + 1 + 2].toInt8() and 0x7F))
}

inline fun ByteArray.action() = this[2].toInt8()

inline fun ByteArray.int(index: Int) = this[index].toInt8()

inline fun ByteArray.toInt(index: Int): Int {
    return (this[index + 0].toInt8() shl 24) +
            (this[index + 1].toInt8() shl 16) +
            (this[index + 2].toInt8() shl 8) +
            (this[index + 3].toInt8())
}

inline fun ByteArray.toLong(index: Int): Long {
    return (this[index + 0].toLong8() shl 56) +
            (this[index + 1].toLong8() shl 48) +
            (this[index + 2].toLong8() shl 40) +
            (this[index + 3].toLong8() shl 32) +
            (this[index + 4].toLong8() shl 24) +
            (this[index + 5].toLong8() shl 16) +
            (this[index + 6].toLong8() shl 8) +
            (this[index + 7].toLong8())
}

fun ByteArray.setLong(index: Int, value: Long): ByteArray {
    this[index + 0] = (value shr 56).toByte()
    this[index + 1] = (value shr 48).toByte()
    this[index + 2] = (value shr 40).toByte()
    this[index + 3] = (value shr 32).toByte()
    this[index + 4] = (value shr 24).toByte()
    this[index + 5] = (value shr 16).toByte()
    this[index + 6] = (value shr 8).toByte()
    this[index + 7] = (value).toByte()
    return this
}

fun ByteArray.setInt8(index: Int, value: Int): ByteArray {
    this[index + 0] = value.toByte()
    return this
}

fun ByteArray.subBytes(index: Int, size: Int): ByteArray {
    val buf = ByteArray(size)
    System.arraycopy(this, index, buf, 0, size)
    return buf
}

inline fun ByteArray.setInt(index: Int, value: Int): ByteArray {
    this[0 + index] = (value shr 24).toByte()
    this[1 + index] = (value shr 16).toByte()
    this[2 + index] = (value shr 8).toByte()
    this[3 + index] = (value).toByte()
    return this
}

inline fun ByteArray.setBytes(index: Int, value: ByteArray): ByteArray {
    System.arraycopy(value, 0, this, index, value.size)
    return this
}

fun ByteArray.toHexString(): String {
    val sb = StringBuilder()
    this.forEach {
        sb.append(String.format("%02x ", it.toInt8()))
    }
    return sb.toString()
}

fun ByteArray.isChecked(): Boolean {

    if (this[size - 1].toInt8() != 0xEF) {
        return false
    }

    var c = 0

    val len = size - 2

    for (i in 3 until len) {
        c = c xor this[i].toInt8()
    }

    return c == this[len].toInt8()
}

fun ByteArray.toMacAddress(): String {
    val sb = StringBuilder()
    this.forEachIndexed { index, byte ->
        if (index == (size - 1)) {
            sb.append(String.format("%02x", byte.toInt8()))
        } else {
            sb.append(String.format("%02x:", byte.toInt8()))
        }
    }
    return sb.toString()
}

